// --------------------------------------------------------------------------------------------------------------------
// <copyright file="DashboardViewModel.cs" company="Concept Architecture">
//   (c) 2010 Muhammad Umer Farooq
// </copyright>
// <summary>
//   Defines the DashboardViewModel type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Hisaab.Client.Modules.Core.Dashboard.ViewModel
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Diagnostics.Contracts;
    using System.Linq;
    using System.Windows.Input;
    using Hisaab.Business.Interfaces;
    using Hisaab.Client.Common;
    using Hisaab.Client.Common.BaseClasses;
    using Hisaab.Client.Common.Services;
    using Hisaab.Client.Model;
    using Hisaab.Common;
    using Microsoft.Practices.Prism.Commands;
    using Microsoft.Practices.Prism.Regions;
    using ServiceLocator = Microsoft.Practices.ServiceLocation.ServiceLocator;

    /// <summary>
    /// Defines the <seealso cref="DashboardViewModel"/> type.
    /// </summary>
    public class DashboardViewModel : TabViewModel, INavigationAware
    {
        /// <summary>
        /// Session manager
        /// </summary>
        private readonly ISession _session;

        /// <summary>
        /// Account manager
        /// </summary>
        private readonly IAccountManager _accountManager;

        /// <summary>
        /// Backing field for account total
        /// </summary>
        private ObservableCollection<KeyValue<Account, decimal>> _accountTotals;

        /// <summary>
        /// Backing field for monthly totals
        /// </summary>
        private ObservableCollection<AccountHistoryData> _monthlyTotals;

        /// <summary>
        /// Member variable _refreshCommand
        /// </summary>
        private ICommand _refreshCommand;

        /// <summary>
        /// Initializes a new instance of the <see cref="DashboardViewModel"/> class.
        /// </summary>
        public DashboardViewModel()
            : this(
            ServiceLocator.Current.GetInstance<IAccountManager>(),
            ServiceLocator.Current.GetInstance<ISession>())
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="DashboardViewModel"/> class.
        /// </summary>
        /// <param name="accountManager">The account manager.</param>
        /// <param name="session">The Session</param>
        public DashboardViewModel(IAccountManager accountManager, ISession session)
        {
            Contract.Requires<ArgumentNullException>(accountManager != null);
            Contract.Requires<ArgumentNullException>(session != null);

            Title = "Dashboard";

            _accountManager = accountManager;
            _session = session;

            Refresh();
        }

        /// <summary>
        /// Gets the refresh command.
        /// </summary>
        public ICommand RefreshCommand
        {
            get
            {
                if (_refreshCommand == null)
                {
                    _refreshCommand = new DelegateCommand(Refresh);
                }

                return _refreshCommand;
            }
        }

        /// <summary>
        /// Gets or sets the account totals.
        /// </summary>
        /// <value>The account totals.</value>
        public ObservableCollection<KeyValue<Account, decimal>> AccountTotals
        {
            get
            {
                return _accountTotals;
            }

            set
            {
                _accountTotals = value;
                RaisePropertyChangedEvent("AccountTotals");
            }
        }

        /// <summary>
        /// Gets or sets the monthly totals.
        /// </summary>
        /// <value>
        /// The monthly totals.
        /// </value>
        public ObservableCollection<AccountHistoryData> MonthlyTotals
        {
            get
            {
                return _monthlyTotals;
            }

            set
            {
                _monthlyTotals = value;
                RaisePropertyChangedEvent("MonthlyTotals");
            }
        }

        /// <summary>
        /// Refreshes this data.
        /// </summary>
        public void Refresh()
        {
            var totals = _accountManager.GetAccountTotals(_session.LoggedUser).Select(x => new KeyValue<Account, decimal> { Key = x.Key.Map<Business.Entities.Account, Account>(), Value = x.Value });
            AccountTotals = new ObservableCollection<KeyValue<Account, decimal>>(totals);

            var list = new List<AccountHistoryData>();
            var accountHistory = _accountManager.GetAllAccountBalance(_session.LoggedUser);
            foreach (var value in accountHistory)
            {
                var accountHistoryData = new AccountHistoryData { Title = value.Key.Name };
                foreach (var data in value.Value)
                {
                    accountHistoryData.Add(data.Map<Business.Entities.AccountMonthlyTotal, AccountMonthlyTotal>());
                }

                list.Add(accountHistoryData);
            }

            MonthlyTotals = new ObservableCollection<AccountHistoryData>(list);
        }

        #region Implementation of INavigationAware

        /// <summary>
        /// Called when [navigated to].
        /// </summary>
        /// <param name="navigationContext">The navigation context.</param>
        public void OnNavigatedTo(NavigationContext navigationContext)
        {
            GlobalCommands.Refresh.RegisterCommand(RefreshCommand);
        }

        /// <summary>
        /// Determines whether [is navigation target] [the specified navigation context].
        /// </summary>
        /// <param name="navigationContext">The navigation context.</param>
        /// <returns>
        ///   <c>true</c> if [is navigation target] [the specified navigation context]; otherwise, <c>false</c>.
        /// </returns>
        public bool IsNavigationTarget(NavigationContext navigationContext)
        {
            return true;
        }

        /// <summary>
        /// Called when [navigated from].
        /// </summary>
        /// <param name="navigationContext">The navigation context.</param>
        public void OnNavigatedFrom(NavigationContext navigationContext)
        {
            GlobalCommands.Refresh.UnregisterCommand(RefreshCommand);
        }

        #endregion Implementation of INavigationAware
    }
}